home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Very Best of Atari Inside
/
The Very Best of Atari Inside 1.iso
/
mint
/
mntlib43
/
mntlib
/
ftw.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-05
|
3KB
|
115 lines
/*
** FTW
** Walk a directory hierarchy from a given point, calling a user-supplied
** function at each thing we find. If we go below a specified depth,
** recycle file descriptors.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <types.h>
#include <stat.h>
#ifdef __TURBOC__
#include <sys\dir.h>
#else
#include <sys/dir.h>
#endif
#include <ftw.h>
#define EQ(a, b) (strcmp((a), (b)) == 0)
int
ftw(directory, funcptr, depth)
char *directory;
int (*funcptr) __PROTO((char *, struct stat *, int));
int depth;
{
register DIR *dirp;
struct direct *entp;
struct stat stats;
register char *p;
register long i;
#ifndef __MINT__
long seekpoint;
#endif
char *fullpath;
#ifndef __MINT__
seekpoint = 0; /* avoid spurious warning from gcc -Wall */
#endif
/* If can't stat, tell the user so. */
if (stat(directory, &stats) < 0)
return (*funcptr)(directory, &stats, FTW_NS);
/* If it's not a directory, call the user's function. */
if ((stats.st_mode & S_IFMT) != S_IFDIR)
/* Saying "FTW_F" here is lying; what if this is a symlink? */
return (*funcptr)(directory, &stats, FTW_F);
/* Open directory; if we can't, tell the user so. */
dirp = opendir(directory);
if (dirp == NULL)
return (*funcptr)(directory, &stats, FTW_DNR);
/* See if user wants to go further. */
i = (*funcptr)(directory, &stats, FTW_D);
if (i) {
closedir(dirp);
return (int)i;
}
/* Get ready to hold the full paths. */
i = strlen(directory);
fullpath = (char *) malloc( (size_t) (i + 1 + MAXNAMLEN + 1) );
if (fullpath == NULL) {
closedir(dirp);
return -1;
}
(void)strcpy(fullpath, directory);
p = &fullpath[i];
if (i && p[-1] != '/')
*p++ = '/';
/* Read all entries in the directory.. */
while ((entp = readdir(dirp)) != 0)
if (!EQ(entp->d_name, ".") && !EQ(entp->d_name, "..")) {
#ifndef __MINT__
if (depth <= 1) {
/* Going too deep; checkpoint and close this directory. */
seekpoint = telldir(dirp);
closedir(dirp);
dirp = NULL;
}
#endif
/* Process the file. */
(void)strcpy(p, entp->d_name);
i = ftw(fullpath, funcptr, depth - 1);
if (i) {
/* User's finished; clean up. */
free(fullpath);
if (dirp)
closedir(dirp);
return (int)i;
}
#ifndef __MINT__
/* Reopen the directory if necessary. */
if (dirp == NULL) {
dirp = opendir(directory);
if (dirp == NULL) {
free(fullpath);
return -1;
}
seekdir(dirp, seekpoint);
}
#endif
}
/* Clean up. */
free(fullpath);
closedir(dirp);
return 0;
}